﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://www.codeplex.com/EmlenMud
using System.Runtime.Serialization;
using System;
using System.Xml.Serialization;
using System.Threading;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BrainTechLLC.ThreadSafeObjects;

namespace BrainTechLLC
{
    public class GoToCommand : Command, ICommandInfo
    {
        public override string HelpText { get { return "Moves to a specific location, specified by the coordinates given"; } }
        public override string Example { get { return "goto 4,5,1"; } }

        [NonSerialized, XmlIgnore]
        public static List<string> Words = new List<string>() { "GOTO" };

        public override List<string> FirstWords { get { return Words; } }

        public override CommandToPerform CreateCommand(IGameThing source, string first, string input)
        {
            var cmd = base.CreateCommand(source, first, input);
            cmd.CheckCanPerformInfo = this.GetType().Name + ".CheckCanPerform";
            return cmd;
        }

        public override bool CheckIsValid(IGameThing source, string first, string input)
        {
            if (string.IsNullOrEmpty(input))
                return false;

            return base.CheckIsValid(source, first, input);
        }

        [MethodVisible]
        public static string CheckCanPerform(CommandToPerform cmd, IGameThing source, IGameThing target, PropertyData args, PropertyData modifyingArguments)
        {
            GameChar gameThing = source as GameChar;

            if (gameThing.IsDead)
                return "You are dead!";

            return string.Empty;
        }


        [MethodVisible]
        public static List<PerceivedEventAndAudience> PerformMethod(CommandToPerform cmd, IGameThing source, IGameThing target, PropertyData args, PropertyData modifyingArguments)
        {
            List<PerceivedEventAndAudience> events = new List<PerceivedEventAndAudience>();
            GameChar sourceChar = source as GameChar;
            string allParams = (cmd.UserInput == null) ? string.Empty : cmd.UserInput;

            GameLocation oldLocation = sourceChar.GameLocation;
            GameLocation newLocation = allParams.ParseLocation();
            
            if (newLocation == null)
                newLocation = oldLocation;

            oldLocation = WorldMap.Instance.ToLocation(sourceChar.AssociatedID, newLocation);
            sourceChar.SetLocationInt(newLocation.XYZ, newLocation.AssociatedID);
            EventToPerceive evtLeave = CreateObservableExit(source);
            EventToPerceive evtEnter = CreateObservableEnter(source, newLocation.XYZ);
            events.Add(new PerceivedEventAndAudience() { Event = evtLeave, Audience = oldLocation.Things });
            events.Add(new PerceivedEventAndAudience() { Event = evtEnter, Audience = newLocation.Things });

            if (sourceChar.Settings.GetArgument<bool>("LookAfterMove"))
            {
                cmd.AdditionalCommand = CommandFactory.CreateLook(sourceChar.AssociatedID, string.Empty);
            }

            return events;
        }

        [MethodVisible]
        public static EventToPerceive CreateObservableExit(IAssociatedID source)
        {
            return new GeneralEventToPerceive()
            {
                ShowToObservers = new Event(string.Format("~source disappears."), ViewType.See),
                Sources = new AssociatedIDCollection(source.AssociatedID)
            };
        }

        [MethodVisible]
        public static EventToPerceive CreateObservableEnter(IAssociatedID source, LocationInt loc)
        {
            return new GeneralEventToPerceive()
            {
                ShowToObservers = new Event(string.Format("~source appears."), ViewType.See),
                ShowToSource = new Event(string.Format("You disappear and reappear at " + loc.ToString()), ViewType.See),
                Sources = new AssociatedIDCollection(source.AssociatedID)
            };
        }
    }    
}

